﻿
using JFTest.Nlog;
using JFTest.Utils;
using Newtonsoft.Json;

using Sunny.UI;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Security.Policy;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
using System.Xml.Linq;
using WindowsFormTest;



namespace JFTest.CommunicationService
{
   
    public class TcpClientDevice : NetworkDevice
    
   {
       
       private Socket _clientSocket;
       private Thread _threadDaq;
       private IPEndPoint _localEndPoint;
       private IPAddress _ipAddress;
       private string rcvString;

       public static event  ShowSocketData ShowData;

        //public static event ShowFrameInfo ShowScanInfo;
        private TaskCompletionSource<string> _readResultTcs;


        public TcpClientDevice(string name, string ip, int port)
        {
            EquipmentName = name;
            DeviceIp = ip;
            DevicePort = port;

          // MULTIPLC.Scann += SendScanCmd;

        }
        public TcpClientDevice(string equipmentName, string equipmentId, string ip, int port = 6666)
        {

            DeviceIp = ip;
            DevicePort = port;

            EquipmentId = equipmentId;
            EquipmentName = equipmentName;

            CloseTag = false;
        }
        /// <summary>
        /// 建立连接
        /// </summary>
        public override bool Connect()
        {


            _ipAddress = IPAddress.Parse(DeviceIp);
            _localEndPoint = new IPEndPoint(_ipAddress, DevicePort);

            // Connect to the remote endpoint
            try
            {
                _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) { ReceiveTimeout = 3000, SendTimeout = 1000 };
                _clientSocket.ReceiveTimeout = -1;//设置超时期限无限大，一直处于接收状态
                _clientSocket.Connect(_localEndPoint);

                IsConnected = true;
                ShowData(EquipmentName + "建立连接");
            }
            catch (Exception e)
            {
                IsConnected = false;
                ShowData(EquipmentName + "服务端连接异常");
                Logger.Error(string.Format("服务端连接异常，机台ip：{0}，异常信息：{1}", DeviceIp, e.Message));
            }
            return IsConnected;
        }
        public override void ReConnect()
        {

            try
            {
                Task.Factory.StartNew(() =>
                {
                    while (!CloseTag)
                    {
                        Thread.Sleep(100);

                        if (CloseTag)//外部给一个关闭信号，不再重新连接
                        {
                            Disconnect();
                            break;
                        }

                        if (_clientSocket == null)
                        {
                            Connect();
                            continue;
                        }
                        
                        if (!_clientSocket.Connected)
                        {

                            Disconnect();
                            Connect();
                            continue;
                        }


                    }

                }, TaskCreationOptions.LongRunning);
            }
            catch (Exception e)
            {
                IsConnected = false;
                Logger.Error(string.Format("TcpClientDevice连接异常，机台ip：{0}，异常信息：{1}", _ipAddress, e.Message));
            }

        }
        /// <summary>
        /// 断开连接
        /// </summary>
        public override void Disconnect()
       {
           try
           {

                if (_clientSocket != null)
                {
                    _clientSocket.Shutdown(SocketShutdown.Both);
                    _clientSocket.Close();
                    _clientSocket.Dispose();
                    _clientSocket = null;
                    IsConnected = false;
                }

                ShowData(EquipmentName + "已经断开连接");
           }
           catch (Exception e)
           {
              // Log.Instance().AddLog(string.Format("{0} 断开CNC连接失败{1}", DeviceIp, e.Message));
               
           }
       }


        public override void DataCollection()
        {
            Task.Run(() =>
            {
                while (true)
                {
                    try
                    {
                        if (IsConnected)
                        {

                            byte[] bytes = new byte[2048];
                            string rcvStr = "";
                            int bytesRec = _clientSocket.Receive(bytes);//阻塞接受
                            Encoding EN = Encoding.GetEncoding("UTF-8");
                            rcvStr = EN.GetString(bytes, 0, bytesRec);
                            rcvString = rcvStr.Trim();
                            
                            Console.WriteLine("接收到字符串："+rcvString+"  "+DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff"));
                            if (rcvString == "")
                            {
                                Console.WriteLine("断开链接：" + _clientSocket.LocalEndPoint + "  " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff"));
                                Disconnect();
                                continue;
                            }
                            JavaScriptSerializer jss = new JavaScriptSerializer();
                            ThreeDCheckParams threeDCheckParams = jss.Deserialize<ThreeDCheckParams>(rcvStr);
                            Console.Write(rcvStr);
                            string result=threeDCheckParams.check_result;
                            _readResultTcs.TrySetResult(rcvStr);
                            ShowData("接收线程："+ result);
                            

                        }
                        else
                        {
                            Console.WriteLine("未连接："  + "  " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff"));
                            Thread.Sleep(1000);
                        }

                    }
                    catch (SocketException e)
                    {
                        

                        if (_clientSocket != null)
                        {
                            _clientSocket.Close();
                            _clientSocket = null;
                        }
                        IsConnected = false;
                        
                    }
                    catch (Exception e)
                    {

                        Logger.Error(string.Format("ModbusTcp采集数据异常，机台ip：{0}，异常信息：{1}", DeviceIp, e.Message));
                    }


                }
            });
        }

        
        public override string SendCommand(string command)
        {
            string result = "OK";
            byte[] msg = new byte[2048];
            msg = Encoding.UTF8.GetBytes(command);
            try
            {
                if (IsConnected)
                {
                    _clientSocket.Send(msg);
                }
            }
            catch (Exception ex)
            {
            }
            finally
            {
            }
            return result;
            
        }
        public async Task<string> SendRcvAsync(string command)
        {
            _readResultTcs = new TaskCompletionSource<string>();
            // 发送数据
            var sendBuffer = Encoding.UTF8.GetBytes(command);
            await _clientSocket.SendAsync(new ArraySegment<byte>(sendBuffer), SocketFlags.None);

            // 接收超时设置
            
            var result = await GetRcvStr();
            
            return result;
        }
        
        public async Task<string> GetRcvStr()
        {
            var receiveTask = _readResultTcs.Task;
            if (await Task.WhenAny(receiveTask, Task.Delay(3000)) != receiveTask)
                return "";
            
            rcvString = "";
            return receiveTask.Result;

        }

        public override string ReceiveData()
        {
            throw new NotImplementedException();
        }
    }
}
